<script lang="ts" setup>
import CodeMirror from 'vue-codemirror6'; //暂时没用

// codemirror api https://codemirror.net/docs/guide/
import { EditorState, Text, Compartment } from '@codemirror/state';
import { basicSetup, EditorView } from 'codemirror';
import { keymap, lineNumbers } from '@codemirror/view';
import { defaultKeymap } from '@codemirror/commands';
import { oneDark } from '@codemirror/theme-one-dark';

import { json, jsonParseLinter } from '@codemirror/lang-json';
import { css } from '@codemirror/lang-css';
import { cpp } from '@codemirror/lang-cpp';
import { html } from '@codemirror/lang-html';
import { java } from '@codemirror/lang-java';
import { javascript as js } from '@codemirror/lang-javascript';
import { markdown as md } from '@codemirror/lang-markdown';
import { python as py } from '@codemirror/lang-python';
import { sql } from '@codemirror/lang-sql';
import { rust } from '@codemirror/lang-rust';
import { vue } from '@codemirror/lang-vue';
import { xml } from '@codemirror/lang-xml';

import { onMounted, reactive, watch } from 'vue';

const props = defineProps({
  theme: {
    type: String,
    default: 'default',
  },
  value: {
    type: String,
    default: 'hello word!', //文本
  },
  fileType: {
    type: String as PropType<string>,
    default: 'json', // 编辑模式(文件类型)
  },
  readOnly: {
    type: Boolean,
    default: false,
  },
  lineNumber: {
    type: Boolean,
    default: false,
  },
});
const emit = defineEmits(['save-file']);

const editorRef: Ref<InstanceType<typeof Element> | undefined> = ref();
const supportType = [
  'cpp',
  'java',
  'sql',
  'py',
  'vue',
  'html',
  'js',
  'json',
  'css',
  'xml',
  'rust',
  'md',
];
const textType = (type: string) => {
  // if (supportType.includes(type)) {
  //   // eval 将字符串转化为函数
  //   return eval(type + '()');
  // } else {
  //   return keymap.of(defaultKeymap);
  // }
  return type == 'json'
    ? json()
    : type == 'css'
    ? css()
    : type == 'cpp'
    ? cpp()
    : type == 'html'
    ? html()
    : type == 'java'
    ? java()
    : type == 'js' || type == 'ts'
    ? js()
    : type == 'md'
    ? md()
    : type == 'py'
    ? py()
    : type == 'sql'
    ? sql()
    : type == 'rust'
    ? rust()
    : type == 'vue'
    ? vue()
    : type == 'xml'
    ? xml()
    : keymap.of(defaultKeymap);
};
onMounted(() => {});
onUnmounted(() => {
  view?.destroy();
});
let view: any;
const init = () => {
  view?.destroy();
  let startState = EditorState.create({
    doc: props.value,
    extensions: [
      props.lineNumber ? basicSetup : [],
      props.theme == 'default' ? [] : oneDark,
      EditorState.readOnly.of(!props.readOnly),
      textType(props.fileType),

      // 自定义主题

      // EditorView.theme(
      //   {
      //     '&': {
      //       color: 'white',
      //       backgroundColor: '#034',
      //     },
      //     '.cm-content': {
      //       caretColor: '#0e9',
      //     },
      //     '&.cm-focused .cm-cursor': {
      //       borderLeftColor: '#0e9',
      //     },
      //     '&.cm-focused .cm-selectionBackground, ::selection': {
      //       backgroundColor: '#074',
      //     },
      //     '.cm-gutters': {
      //       backgroundColor: '#045',
      //       color: '#ddd',
      //       border: 'none',
      //     },
      //   },
      //   { dark: true },
      // ),
    ],
    // extensions: [keymap.of(defaultKeymap)],
  });
  view = new EditorView({
    state: startState,
    parent: unref(editorRef),
  });
};

watch(
  () => props,
  (n) => {
    throttle(init);
  },
  {
    deep: true,
  },
);
//节流
let timer_throttle: any;
const throttle = (fn: Function, wait?: number) => {
  wait = wait || 100;
  if (!timer_throttle) {
    timer_throttle = setTimeout(() => {
      fn.apply(this);
      timer_throttle = null;
    }, wait);
  }
};

// watch(
//   () => props.value,
//   (n) => {
//     init();
//   },
// );
// watch(
//   () => props.readOnly,
//   (n) => {
//     init();
//   },
// );
// watch(
//   () => props.lineNumber,
//   (n) => {
//     init();
//   },
// );
// watch(
//   () => props.theme,
//   (n) => {
//     init();
//   },
// );

const getValue = () => {
  console.log(view?.state.doc.toString());
  emit('save-file', view?.state.doc.toString());
};
</script>
<template>
  <div ref="editorRef"></div>
  <!-- <code-mirror v-modal="value" :extensions /> -->
</template>
<style lang="less" scoped></style>
